// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Helps generate requests to JSON data and iframes to
 * detect caching behavior for JSON requests.
 * @author j.s@google.com (Jeff Scudder)
 */

/**
 * Namespace for detecting duplicate JSON requests.
 * @type {Object}
 */
var jt = {};

/**
 * Enum specifying the different ways the JSON can be loaded.
 * @enum {Number}
 */
jt.RequestTypes = {
  APPEND_CHILD_MODE: 1,
  DOCUMENT_WRITE_MODE: 2
};

/**
 * Set this to control which way the parent page requests the JSON when
 * prefetching.
 * @type {jt.RequestTypes}
 */
jt.parentMode = jt.RequestTypes.DOCUMENT_WRITE_MODE;
//jt.parentMode = jt.RequestTypes.APPEND_CHILD_MODE;

/**
 * Controls how the child iframe requests the duplicate JSON.
 * @type {jt.RequestTypes}
 */
jt.childMode = jt.RequestTypes.DOCUMENT_WRITE_MODE;
//jt.childMode = jt.RequestTypes.APPEND_CHILD_MODE;

/**
 * A class that is able to both prefetch the JSON as well as request an iframe
 * that will request the same JSON.
 * @constructor
 */
jt.Client = function() {
  // For the iframe, the ID of the JSON request will be in the page URL.
  var query = window.location.search;
  if (query) {
    this.currentId = query.substr(1);
  } else {
    this.currentId = null;
  }
};

/**
 * Sets the currentId to a random value, prepare to make a request.
 */
jt.Client.prototype.generateNewRequestId = function()  {
  this.currentId =
      ('' + Math.floor(Math.random() * 1000)) + (new Date()).getTime();
};

/**
 * Requests the JSON data in the specified mode, either using document.write
 * or appendChild.
 * @param {jt.RequestTypes} mode The mechanism used to request the JSON.
 */
jt.Client.prototype.fetchJson = function(mode) {
  var output = document.createElement('p');
  output.appendChild(
      document.createTextNode('Requesting JSON ' + this.currentId));
  document.getElementById('output').appendChild(output);
  if (mode == jt.RequestTypes.APPEND_CHILD_MODE) {
    var script = document.createElement('script');
    script.src = '/jsonData.js?currentId=' + this.currentId;
    document.body.appendChild(script);
  } else {
    document.write('<script src="/jsonData.js?currentId=' + this.currentId +
                   '"></script>');
  }
};

/**
 * Requests the JSON data, used in the parent page.
 */
jt.Client.prototype.parentFetchJson = function() {
  this.fetchJson(jt.parentMode);
};

/**
 * Requests the JSON data, used in the iframe.
 */
jt.Client.prototype.childFetchJson = function() {
  this.fetchJson(jt.childMode);
};

/**
 * Build the iframe that will display the data. Its JSON should load from
 * cache.
 */
jt.Client.prototype.loadIframe = function() {
  document.body.appendChild(document.createElement('br'));
  var iframe = document.createElement('iframe');
  iframe.src = '/jsonIframe?' + this.currentId;
  iframe.width = '800px';
  iframe.height = '200px';
  document.getElementById('iframe-container').appendChild(iframe);
};

/**
 * Called when the JSON is returned by the server. In the parent page we
 * want the completion of the JSON prefetch to trigger the creation of
 * the iframe whose JSON request we wanted to prefetch.
 * @param {string} data The response from the server. We want to make sure
 *     that the data in the iframe matches that received by the parent, make
 *     sure that in the iframe this comes from the cache.
 */
window['renderJson'] = function(data) {
  var output = document.createElement('p');
  output.appendChild(document.createTextNode('Data from server: ' + data));
  document.getElementById('output').appendChild(output);
  // In the parent page, we want the JSON response to trigger the request
  // for the iframe.
  if (window['parentClient']) {
    window['parentClient'].loadIframe();
  }
};
